#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<fstream>
#include<string>
#include<unordered_set>
using namespace std;

inline void swap(char* s,int lIndex,int rIndex){
    int len = strlen(s);
    // 边界检查，防止错误；
    if(lIndex>=0&&(lIndex<rIndex&&rIndex<=len)){
        char temp = s[lIndex];
        s[lIndex] = s[rIndex];
        s[rIndex] = temp;
    }
}
// 核心的交换回溯算法，使用集合来去重
void getPermutation(unordered_set<string>& st,char* s,int k){
    if(k==std::strlen(s)){
        st.emplace(s);
    }
    // 通过交换字符位置来避免插入操作的开销
    /*
     * 1.k位置和自身交换将递归进入的初始状态也保留下来作为下次递归的开始；
     * 2.二次交换是在退出回溯分支的时候回复排序状态
     */
    for(int i=k;i<std::strlen(s);++i){
        swap(s,k,i);
        getPermutation(st,s,k+1);
        swap(s,k,i);

    }

}
// 用来给c字符串排下序，其实可以不做的
int char_cmp(const void* lhs,const void* rhs){
    return (*(int*)lhs-*(int*)rhs); // 按照计算结果为负来排？
}
// 这个函数可以用 less<string> 这是一个实现增序的比较器函数模板；
bool mycmp( const string &lhs, const string& rhs){
    return lhs<rhs; 
}
// 主函数可以用命令行来指定输出文件的名称、路径；
int main(int argc,char* args[]){
    ofstream file;
    file.open(args[1]);
    if(file.fail()){
        cout<<"文件打开失败"<<endl;
        exit(0);
    }else{

    char inStr[7];
    // 全排列复杂度较高，使用较短的字符串来测试；
    scanf("%s",inStr);
    qsort(inStr,strlen(inStr),sizeof(char),char_cmp);
    unordered_set<string> ans;
    getPermutation(ans,inStr,0);
    // 集合是无序的，通过迭代器范围构造一个vector 来做排序容器；
    vector<string> ansorder(ans.begin(),ans.end()); 
    sort(ansorder.begin(),ansorder.end(),mycmp);
    for(auto str:ansorder){
        
        file<<str<<"\n";
    }
    file.close();
    cout<<"处理结束"<<endl;

    }
    
    

}
